package com.bytedance.testtools.view

import android.content.Context
import android.graphics.*
import android.view.MotionEvent
import android.widget.FrameLayout
import java.util.*

class TrackDrawView(context: Context): FrameLayout(context) {

    private val TAG = "TrackDrawView"
    private val eventQueue: Queue<SimpleEvent> = ArrayDeque()
    private val mPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val mColors = arrayOf(Color.RED, Color.YELLOW, Color.GREEN,
                                            Color.BLUE, Color.GRAY, Color.MAGENTA,
                                            Color.CYAN, Color.BLACK)

    init {
        mPaint.strokeWidth = 15.0f
        mPaint.textSize = 24.0f
        mPaint.style = Paint.Style.STROKE
        mPaint.strokeCap = Paint.Cap.ROUND
        mPaint.strokeJoin = Paint.Join.ROUND
        setWillNotDraw(false)
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        //Log.d(TAG, event.toString())
        when(val action = ev.actionMasked){
            MotionEvent.ACTION_DOWN,
            MotionEvent.ACTION_UP,
            MotionEvent.ACTION_POINTER_DOWN,
            MotionEvent.ACTION_POINTER_UP,
            MotionEvent.ACTION_MOVE -> {
                val count = ev.pointerCount
                for (i in 0 until count){
                    val x = ev.getX(i)
                    val y = ev.getY(i)
                    val event = SimpleEvent( i, x, y, action, ev.downTime, ev.eventTime)
                    val last = eventQueue.lastOrNull()
                    if (last == null || last != event){
                        eventQueue.offer(event)
                        invalidate()
                    }
                }
            }
        }
        return true
    }

   // private val textRect: Rect = Rect()
    private val tracks = mutableMapOf<String, Path>()
    override fun onDraw(canvas: Canvas) {
        while (eventQueue.isNotEmpty()){
            val event = eventQueue.remove()
            if (event.type == MotionEvent.ACTION_DOWN || event.type == MotionEvent.ACTION_POINTER_DOWN){
                var path = tracks["${event.id}#${event.downTime}"]
                if (path == null){
                    path = Path()
                    tracks["${event.id}#${event.downTime}"] = path
                }
                path.moveTo(event.x, event.y)
            }
            if (event.type == MotionEvent.ACTION_MOVE){
                val path = tracks["${event.id}#${event.downTime}"]
                path?.lineTo(event.x, event.y)
            }
            if (event.type == MotionEvent.ACTION_UP || event.type == MotionEvent.ACTION_POINTER_UP){
                val path = tracks.remove("${event.id}#${event.downTime}")
                path?.run {
                    tracks["${event.id}#${event.downTime}#${event.eventTime}"] = this
                }
            }

        }
        tracks.forEach{
            val (timeId, path) = it
            val id = timeId.split("#")[0].toInt()
            mPaint.color = mColors[id % mColors.size]
            canvas.drawPath(path, mPaint)
        }
    }

    fun clear(){
        tracks.clear()
        invalidate()
    }

}

data class SimpleEvent(
    val id: Int,
    val x: Float,
    val y: Float,
    val type: Int,
    val downTime: Long,
    val eventTime: Long
){
    fun getActionDesc() = when(type){
        MotionEvent.ACTION_DOWN -> "ACTION_DOWN"
        MotionEvent.ACTION_MOVE -> "ACTION_MOVE"
        MotionEvent.ACTION_UP -> "ACTION_UP"
        MotionEvent.ACTION_POINTER_UP -> "ACTION_POINTER_UP"
        MotionEvent.ACTION_POINTER_DOWN -> "ACTION_POINTER_DOWN"
        else -> "UNKNOWN"
    }

    override fun toString(): String {
        return super.toString() + "-->"+ getActionDesc()
    }
}
